package com.tjetc.test.config;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author gaoyongxiang
 * @version v1.0
 * @date 2025/9/9
 */
@Configuration
@MapperScan("com.tjetc.test.mapper")
public class MybatisConfig {
    /*
        ● SqlSessionFactoryBuilder
            这个类可以被实例化、使用和丢弃，一旦创建了 SqlSessionFactory，就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域（也就是局部方法变量）。 无需ioc容器管理
        ●  SqlSessionFactory
            一旦被创建就应该在应用的运行期间一直存在，没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次，因此 SqlSessionFactory 的最佳作用域是应用作用域。 需要ioc容器管理
        ●  SqlSession
            每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的，因此是不能被共享的，所以它的最佳的作用域是请求或方法作用域。 无需ioc容器管理
        ●  Mapper映射器实例
            映射器是一些绑定映射语句的接口。映射器接口的实例是从 SqlSession 中获得的。虽然从技术层面上来讲，任何映射器实例的最大作用域与请求它们的 SqlSession 相同。但方法作用域才是映射器实例的最合适的作用域。
        从作用域的角度来说，映射器实例不应该交给ioc容器管理
        但是从使用的角度来说，业务类（service）需要注入mapper接口，所以mapper应该交给ioc容器管理

     */

    // 这种方法保留了原始的mybatis的配置文件
//    @Bean
//    public SqlSessionFactory sqlSessionFactory() throws IOException {
//        // 建议使用类路径下的资源文件进行配置 配置文件
//        String resource = "mybatis-config.xml";
//        // 从类路径下拿到配置文件
//        InputStream inputStream = Resources.getResourceAsStream(resource);
//        // 构建SqlSessionFactory对象 通过SqlSessionFactoryBuilder 中的build 方法进行构建
//        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        return sqlSessionFactory;
//    }
//    配置sqlSessionFactory
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//        setting相关的配置
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 开启驼峰转换
        configuration.setMapUnderscoreToCamelCase(true);
        sqlSessionFactoryBean.setConfiguration(configuration);
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 配置映射文件的位置
        sqlSessionFactoryBean.setMapperLocations(
                new PathMatchingResourcePatternResolver()
                        .getResources("classpath:mapper/*.xml"));
        return sqlSessionFactoryBean;
    }

    // 配置mapper接口的扫描
//    @Bean
//    public MapperScannerConfigurer mapperScannerConfigurer() {
//        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
//        mapperScannerConfigurer.setBasePackage("com.tjetc.test.mapper");
//        return mapperScannerConfigurer;
//    }
}